﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.RelyingParty;
using SocialPhotos.Models;
using SocialPhotos.Models.Entities;
using SocialPhotos.Models.SqlExpressRepository;
using SocialPhotos.Web.Models;

namespace SocialPhotos.Web.Controllers
{
    public class AccountController : BaseController
    {
        private static readonly OpenIdRelyingParty openId = new OpenIdRelyingParty();
        private readonly IUserRepository userRepository = new SqlExUserRepository();

        //
        // GET: /Account/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Logon()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Logon(LogonViewModel model, string returnUrl)
        {
            if (ModelState.IsValid && model.User != null)
            {
                if (userRepository.VerifyUser(model.User.Name, model.User.Password))
                {
                    var ticket = new FormsAuthenticationTicket(1, model.User.Name.ToString(), DateTime.Now, DateTime.Now.AddMinutes(60), false, "");
                    var strEncryptedTicket = FormsAuthentication.Encrypt(ticket);
                    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strEncryptedTicket);
                    Response.Cookies.Add(cookie);
                    return RedirectToAction("Index", "Home");
                }
            }
            return View(model);
        }

        public ActionResult Logout()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }

        [ValidateInput(false)]
        public ActionResult Authenticate(string returnUrl)
        {
            var response = openId.GetResponse();
            if (response == null)
            {
                //Let us submit the request to OpenID provider
                Identifier id;
                if (Identifier.TryParse(Request.Form["openid_identifier"], out id))
                {
                    try
                    {
                        var request = openId.CreateRequest(Request.Form["openid_identifier"]);
                        return request.RedirectingResponse.AsActionResult();
                    }
                    catch (ProtocolException ex)
                    {
                        ViewBag.Message = ex.Message;
                        return View("LogOn");
                    }
                }

                ViewBag.Message = "Invalid identifier";
                return View("LogOn");
            }

            LogonViewModel viewModel = new LogonViewModel();
            //Let us check the response
            switch (response.Status)
            {
                case AuthenticationStatus.Authenticated:
                    viewModel.IsValidProvider = true;
                    viewModel.User =userRepository.GetUserByProviderKey(response.ClaimedIdentifier);
                    if (viewModel.User == null)
                    {
                        viewModel.User = new User();
                        viewModel.User.ProviderKey = response.ClaimedIdentifier;
                        viewModel.IsExistedUser = false;
                        viewModel.LoginStatus = "The provider has authenticated your account. Please mapping it with an account in out site.";
                    }
                    else
                    {
                        viewModel.IsExistedUser = true;
                        var ticket = new FormsAuthenticationTicket(1, viewModel.User.Name.ToString(), DateTime.Now, DateTime.Now.AddMinutes(60), false, "");
                        var strEncryptedTicket = FormsAuthentication.Encrypt(ticket);
                        var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strEncryptedTicket);
                        Response.Cookies.Add(cookie);
                        return RedirectToAction("Index", "Home");
                    }
                    
                    return View("LogOn", viewModel);

                    //LogOnModel lm = new LogOnModel();
                    //lm.OpenID = response.ClaimedIdentifier;
                    ////check if user exist
                    //MembershipUser user = MembershipService.GetUser(lm.OpenID);
                    //if (user != null)
                    //{
                    //    lm.UserName = user.UserName;
                    //    FormsService.SignIn(user.UserName, false);
                    //}

                    //return View("LogOn", lm);)

                case AuthenticationStatus.Canceled:
                    viewModel.LoginStatus = "The provide has canceled your credential";
                    viewModel.IsValidProvider = false;
                    return View("LogOn", viewModel);

                case AuthenticationStatus.Failed:
                    viewModel.LoginStatus = response.Exception.Message;
                    viewModel.IsValidProvider = false;
                    return View("LogOn", viewModel);
            }

            return new EmptyResult();
        }

        [ValidateInput(false)]
        public ActionResult GetAuthenticate(string returnUrl)
        {
            var response = openId.GetResponse();
            if (response == null)
            {
                //Let us submit the request to OpenID provider
                Identifier id;
                if (Identifier.TryParse(Request.Form["openid_identifier"], out id))
                {
                    try
                    {
                        var request = openId.CreateRequest(Request.Form["openid_identifier"]);
                        return request.RedirectingResponse.AsActionResult();
                    }
                    catch (ProtocolException ex)
                    {
                        ViewBag.Message = ex.Message;
                        return View("CreateUser");
                    }
                }

                ViewBag.Message = "Invalid identifier";
                return View("CreateUser");
            }

            LogonViewModel viewModel = new LogonViewModel();
            //Let us check the response
            switch (response.Status)
            {
                case AuthenticationStatus.Authenticated:
                    viewModel.IsValidProvider = true;
                    viewModel.User = userRepository.GetUserByProviderKey(response.ClaimedIdentifier);
                    if (viewModel.User == null)
                    {
                        viewModel.User = new User();
                        viewModel.User.ProviderKey = response.ClaimedIdentifier;
                    }
                    else
                    {
                        viewModel.IsExistedUser = true;
                    }

                    return View("CreateUser", viewModel);

                case AuthenticationStatus.Canceled:
                    viewModel.LoginStatus = "The provide has canceled your credential";
                    viewModel.IsValidProvider = false;
                    return View("CreateUser", viewModel);

                case AuthenticationStatus.Failed:
                    viewModel.LoginStatus = response.Exception.Message;
                    viewModel.IsValidProvider = false;
                    return View("CreateUser", viewModel);
            }

            return new EmptyResult();
        }

        public ActionResult CreateUser()
        {
            return View();
        }

        [HttpPost]
        public ActionResult CreateUser(LogonViewModel viewModel)
        {
            if (ModelState.IsValid)
            {
            if (userRepository.CreateUser(viewModel.User.ProviderKey, viewModel.User.Name, viewModel.User.Password))
            {
                var ticket = new FormsAuthenticationTicket(1, viewModel.User.Name, DateTime.Now, DateTime.Now.AddMinutes(60), false, "");
                var strEncryptedTicket = FormsAuthentication.Encrypt(ticket);
                var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, strEncryptedTicket);
                Response.Cookies.Add(cookie);
                return RedirectToAction("Index", "Home");
            }
            }
            return View(viewModel);
        }

    }
}
